package com.kai.service.system.service.impl;

import com.kai.service.article.mapper.ArticleMapper;
import com.kai.service.data.response.system.dto.SevenDaysDataDto;
import com.kai.service.data.response.system.dto.SevenDaysModuleDataDto;
import com.kai.service.data.response.system.statistical.SevenDaysDataResponse;
import com.kai.service.data.response.system.statistical.SevenDaysModuleDataResponse;
import com.kai.service.data.response.system.statistical.TodayDataResponse;
import com.kai.service.message.mapper.MessageBoardMapper;
import com.kai.service.system.entity.SystemLog;
import com.kai.service.system.mapper.SystemLogMapper;
import com.kai.service.system.service.ISystemLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kai.service.user.mapper.UserMapper;
import com.kai.service.util.ExecutorUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统访问日志 服务实现类
 * </p>
 *
 * @author wjk
 * @since 2022-04-19
 */
@Service
public class SystemLogServiceImpl extends ServiceImpl<SystemLogMapper, SystemLog> implements ISystemLogService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private ArticleMapper articleMapper;

    @Resource
    private MessageBoardMapper messageBoardMapper;

    /**
     * 记录日志
     *
     * @param url
     * @param ip
     */
    @Override
    public void addSystemLog(String url, String ip) {
//        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
//        String username;
//        if (authentication.getPrincipal() instanceof LoginUserInfo) {
//            LoginUserInfo loginUserInfo = (LoginUserInfo) authentication.getPrincipal();
//            username = loginUserInfo.getUsername();
//        } else {
//            username = "tourists";
//        }
//
//        ExecutorUtil.execute(() -> {
//            SystemLog systemLog = new SystemLog()
//                    .setUsername(username)
//                    .setIpAddress(ip)
//                    .setPortAddress(url)
//                    .setCreateDatetime(new Date());
//            this.save(systemLog);
//        });
    }

    /**
     * 统计当天数据
     *
     * @return
     */
    @Override
    public TodayDataResponse todayData() {
        TodayDataResponse todayDataResponse = new TodayDataResponse();
        // 访问量
        Integer access = this.baseMapper.todayAccessCount();
        todayDataResponse.setAccess(access);
        // 新增用户
        Integer newUser = userMapper.todayNewUser();
        todayDataResponse.setNewUser(newUser);
        // 新增文章
        Integer newArticle = articleMapper.todayNewArticle();
        todayDataResponse.setNewArticle(newArticle);
        // 新增留言
        Integer newMessage = messageBoardMapper.todayNewMessage();
        todayDataResponse.setNewMessage(newMessage);

        return todayDataResponse;
    }

    /**
     * 统计七天数据
     *
     * @return
     */
    @Override
    public SevenDaysDataResponse sevenDaysData() {
        SevenDaysDataResponse sevenDayResponse = new SevenDaysDataResponse();
        // 获取最近七天日期
        List<String> times = getSpecifiedNumberOfDaysDate(7);
        // 最近七天每日访问量
        SevenDaysDataDto accessCount = this.baseMapper.sevenDaysAccessCount(times);
        sevenDayResponse.setAccessCounts(mapConvertList(accessCount));
        //最近七天新增用户
        SevenDaysDataDto newUser = userMapper.sevenDaysNewUser(times);
        sevenDayResponse.setNewUsers(mapConvertList(newUser));
        //最近七天新增文章
        SevenDaysDataDto newArticle = articleMapper.sevenDaysNewArticle(times);
        sevenDayResponse.setNewArticles(mapConvertList(newArticle));
        //最近七天新增留言
        SevenDaysDataDto newMessage = messageBoardMapper.sevenDaysNewMessage(times);
        sevenDayResponse.setNewMessages(mapConvertList(newMessage));
        // 时间
        sevenDayResponse.setTimes(times);

        return sevenDayResponse;
    }

    /**
     * 统计七天模块数据
     *
     * @return
     */
    @Override
    public SevenDaysModuleDataResponse sevenDaysModuleData() {
        // 获取最近七天日期
        List<String> times = getSpecifiedNumberOfDaysDate(7);

        // 最近七天模块每日访问量
        List<SevenDaysDataDto> sevenDaysModuleDataList = this.baseMapper.sevenDaysModuleData(times);

        // 模块数据集合
        List<SevenDaysModuleDataDto> dataList = sevenDaysModuleDataList.stream().map(dayModuleData -> {
            SevenDaysModuleDataDto moduleData = new SevenDaysModuleDataDto();
            String moduleName = getModuleNameByPortAddress(dayModuleData.getPortAddress());
            moduleData.setModuleName(moduleName);
            moduleData.setSevenData(mapConvertList(dayModuleData));

            return moduleData;
        }).filter(moduleData -> StringUtils.isNotBlank(moduleData.getModuleName())).collect(Collectors.toList());

        return new SevenDaysModuleDataResponse()
                .setTimes(times)
                .setDataList(dataList);
    }

    /**
     * 获取模块名称
     *
     * @param portAddress
     * @return
     */
    private static String getModuleNameByPortAddress(String portAddress) {
        switch (portAddress) {
            case "article":
                return "文章";
            case "problem":
                return "问答";
            case "message":
                return "留言板";
            default:
                return "";
        }
    }

    /**
     * map转换成集合数据
     * @param sevenDaysDataDto
     * @return
     */
    private static List<Integer> mapConvertList(SevenDaysDataDto sevenDaysDataDto){
        List<Integer> data = new ArrayList<>();
        data.add(sevenDaysDataDto.getSeven());
        data.add(sevenDaysDataDto.getSix());
        data.add(sevenDaysDataDto.getFive());
        data.add(sevenDaysDataDto.getFour());
        data.add(sevenDaysDataDto.getThree());
        data.add(sevenDaysDataDto.getTwo());
        data.add(sevenDaysDataDto.getOne());

        return data;
    }

    /**
     * 获取指定的天数日期
     *
     * @param days 获取几天的日期
     * @return 时间集合 正序
     */
    private static List<String> getSpecifiedNumberOfDaysDate(int days){
        Date nowDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(nowDate);

        List<String> times = new ArrayList<>();
        calendar.add(Calendar.DATE,1 - days);
        String one = sdf.format(calendar.getTime());
        times.add(one);

        for (int i = 0; i < days - 1; i++){
            calendar.add(Calendar.DATE,1);
            String date = sdf.format(calendar.getTime());
            times.add(date);
        }

        return times;
    }
}
